home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / FMAZ20.ZIP / FASTMAZE.C next >
C/C++ Source or Header  |  1994-10-24  |  69KB  |  1,871 lines

  1. /*
  2.                                FMAZ20 -- Maze Game
  3.  
  4.                               Version 2.0 (10/24/94)
  5.  
  6.  
  7.      Generate and solve mazes on your VGA (or better) display.
  8.  
  9.      The mazes are displayed in three dimensions.
  10.  
  11.      You will be prompted for the number of columns, the tilt, and a random 
  12. number seed. 
  13.  
  14.      While the maze is being generated, a spinning cursor is displayed.
  15.  
  16.      After the maze is displayed, you may use the arrow keys to solve it.
  17. Press "Q" to quit or press "S" to have the computer solve the maze.
  18.  
  19.      After the maze is solved, you must press some key to continue.
  20.  
  21.      Each maze has exactly one solution that does not involve backtracking
  22. (passing through a doorway more than once).
  23.  
  24.      This program was written by James L. Dean.
  25.  
  26. */
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <math.h>
  30. #include <stdlib.h>
  31. #include <conio.h>
  32. #include <dos.h>
  33. #include <graphics.h>
  34.  
  35. #define TRUE -1
  36. #define FALSE 0
  37.  
  38. /* screen constants */
  39. #define HEIGHT_OF_SCREEN_IN_INCHES       6
  40. #define WIDTH_OF_SCREEN_IN_INCHES        8
  41.  
  42. /* graphics adapter constants */
  43. #define GRAPHICS_DRIVER                VGA /* 640x480x16 VGA */
  44. #define GRAPHICS_MODE                VGAHI /* must support red, green, yellow,
  45.                                               and 5 shades of gray */
  46. #define NUM_X_PIXELS                   640
  47. #define NUM_Y_PIXELS                   480
  48. #define X_PIXEL_MIN                     10
  49. #define X_PIXEL_MAX                    629
  50. #define Y_PIXEL_MIN                      5
  51. #define Y_PIXEL_MAX                    474
  52. #define NUM_COLORS                      16
  53. #define TOP_WALL_COLOR                  12 /* all but last 3 colors are gray */
  54. #define FLOOR_COLOR                      9
  55. #define LEFT_WALL_COLOR                  6
  56. #define FRONT_WALL_COLOR                 3
  57. #define RIGHT_WALL_COLOR                 1
  58. #define BACKOUT_COLOR                   13
  59. #define ADVANCE_COLOR                   14
  60. #define SOLUTION_COLOR                  15
  61.  
  62. /* maze constants */
  63. #define ROOM_HEIGHT_IN_Y_PIXELS         50
  64. #define MIN_WALL_WIDTH_IN_X_PIXELS       3
  65. #define ROOM_WIDTH_TO_WALL_WIDTH_RATIO   2 /* room excludes wall */
  66.  
  67.  
  68. typedef struct corner_record
  69.           {
  70.             int x;
  71.             int y;
  72.           } corner_rec;
  73.  
  74. typedef struct stack_rec_record
  75.           {
  76.             char index_1;
  77.             int  index_2;
  78.           } stack_rec;
  79.  
  80. static void           display_maze(int,int,int,int,char **);
  81. static void           display_solution(int,int,int,int,char **);
  82. static void           draw_line(int,int,int,int,int,int);
  83. static void           generate_maze(int,int,int,int,int,char **,stack_rec *,
  84.                        char *);
  85. static void           get_corners(double);
  86. static void           get_cursor(unsigned char *,unsigned char *,
  87.                        unsigned char *,unsigned char *);
  88. static void           get_defaults(char *,int *,double *,char *);
  89. static void           hash(int *,int *,int *,int *,int *,int *,int *,int *);
  90. static void           increment(int *,int *,int *,int *,int *,int *,int *,
  91.                        int *);
  92. static void           let_user_try_to_solve(int *,int,int,int,int,char **,
  93.                        char **);
  94.        void           main(int,char **);
  95.        void interrupt new_critical_error_handler(void);
  96.        void interrupt (*old_critical_error_handler)(void);
  97. static void           output_wall(int,int,int,int,int,int,int,int,int,int,int,
  98.                        int,int,int,int);
  99. static void           put_defaults(char *,int,double,char *);
  100. static void           set_cursor_position(unsigned char,unsigned char);
  101. static void           set_cursor_size(unsigned char,unsigned char);
  102. static void           solve_maze(int,int,int *,int *,char **,stack_rec *);
  103. static void           titillate(void);
  104.  
  105. extern unsigned _stklen=0x8000;
  106.  
  107. static unsigned char cursor_column;
  108. static unsigned char cursor_row;
  109. static unsigned char cursor_start;
  110. static unsigned char cursor_stop;
  111. static int           delta_x [4] [24];
  112. static int           delta_y [4] [24];
  113. static int           file_opened;
  114. static char          titillator [4] = {'|','/','-','\\'};
  115. static int           titillator_index;
  116. static int           x_corner [2] [2] [2];
  117. static int           y_corner [2] [2] [2];
  118.  
  119. void main(
  120.   int  argc,
  121.   char *argv[])
  122.     {
  123.       register int                color_num;
  124.       static   char               **computer_page;
  125.       static   int                default_num_columns;
  126.       static   char               default_seed [256];
  127.       static   double             default_tilt;
  128.       static   int                ErrorCode;
  129.       static   int                fatal_error;
  130.       static   int                GraphDriver;
  131.       static   int                GraphMode;
  132.       static   char               line [256];
  133.       static   char               *line_ptr;
  134.       static   int                max_num_columns;
  135.       static   int                max_x;
  136.       static   int                max_x_plus_1;
  137.       static   int                max_y;
  138.       static   int                max_y_plus_1;
  139.       static   int                min_num_columns;
  140.       static   int                memory_allocated;
  141.       static   int                num_columns;
  142.       static   int                num_assigned;
  143.       static   int                num_rooms_in_maze;
  144.       static   int                num_rows;
  145.       static   struct palettetype palette;
  146.       static   int                response;
  147.       static   char               seed [256];
  148.       static   int                seed_index;
  149.       static   stack_rec          *stack;
  150.       static   double             tilt;
  151.       static   int                tint;
  152.       static   char               **user_page;
  153.       static   int                user_still_interested;
  154.       static   int                x;
  155.   
  156.       max_num_columns=((X_PIXEL_MAX-X_PIXEL_MIN)/MIN_WALL_WIDTH_IN_X_PIXELS-1)
  157.        /(ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2);
  158.       min_num_columns=(2*WIDTH_OF_SCREEN_IN_INCHES)/HEIGHT_OF_SCREEN_IN_INCHES;
  159.       if (min_num_columns*HEIGHT_OF_SCREEN_IN_INCHES
  160.        < 2*WIDTH_OF_SCREEN_IN_INCHES)
  161.         min_num_columns++;
  162.       fatal_error=FALSE;
  163.       get_defaults(argv[0],&default_num_columns,&default_tilt,
  164.        &default_seed[0]);
  165.       do
  166.         {
  167.           clrscr();
  168.           printf(
  169. "                              FMAZ20 -- Maze Game\n\n"
  170. "                             Version 2.0 (10/24/94)\n\n\n"
  171. "     Generate and solve mazes on your VGA (or better) display.\n\n"
  172. "     The mazes are displayed in three dimensions.\n\n"
  173. "     To get the value surrounded by [], just press Enter.\n\n");
  174.           do
  175.             {
  176.               printf("     Number of columns (%d to %d, or 0 to exit) [%d]?  ",
  177.                min_num_columns,max_num_columns,default_num_columns);
  178.               fflush(stdin);
  179.               fgets(&line[0],256,stdin);
  180.               line_ptr=&line[0];
  181.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  182.                 line_ptr++;
  183.               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  184.                 num_columns=default_num_columns;
  185.               else
  186.                 {
  187.                   num_assigned=sscanf(line_ptr,"%d",&num_columns);
  188.                   if ((num_assigned == 0) || (num_assigned == EOF))
  189.                     num_columns=-1;
  190.                 }
  191.             }
  192.           while ((num_columns != 0)
  193.           &&     ((num_columns < min_num_columns) 
  194.                || (num_columns > max_num_columns)));
  195.           user_still_interested=num_columns;
  196.           if (user_still_interested)
  197.             {
  198.               printf("\n");
  199.               num_rows=HEIGHT_OF_SCREEN_IN_INCHES
  200.                *num_columns/WIDTH_OF_SCREEN_IN_INCHES;
  201.               do
  202.                 {
  203.                   printf("     Tilt (30 to 60 degrees) [%lf]?  ",default_tilt);
  204.                   fflush(stdin);
  205.                   fgets(&line[0],256,stdin);
  206.                   line_ptr=&line[0];
  207.                   while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  208.                     line_ptr++;
  209.                   if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  210.                     tilt=default_tilt;
  211.                   else
  212.                     {
  213.                       num_assigned=sscanf(line_ptr,"%lf",&tilt);
  214.                       if ((num_assigned == 0) || (num_assigned == EOF))
  215.                         tilt=(double) 0.0;
  216.                     }
  217.                 }
  218.               while ((tilt < (double) 30.0) || (tilt > (double) 60.0));
  219.               printf("\n     Random number seed (8 or fewer digits) [%s]?  ",
  220.                &default_seed[0]);
  221.               fflush(stdin);
  222.               fgets(&line[0],256,stdin);
  223.               line_ptr=&line[0];
  224.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  225.                 line_ptr++;
  226.               if ((*line_ptr != '\n') && (*line_ptr != '\0'))
  227.                 {
  228.                   seed_index=0;
  229.                   while ((seed_index < 8) 
  230.                   &&     (*line_ptr)
  231.                   &&     (*line_ptr != '\n'))
  232.                     default_seed[seed_index++]=*(line_ptr++);
  233.                   default_seed[seed_index]='\0';
  234.                 }
  235.               strcpy(&seed[0],&default_seed[0]);
  236.               default_num_columns=num_columns;
  237.               default_tilt=tilt;
  238.               num_rooms_in_maze=num_columns*num_rows;
  239.               if ((stack
  240.                =(stack_rec *) malloc(num_rooms_in_maze*sizeof(stack_rec)))
  241.                == NULL)
  242.                 {
  243.                   printf("     Fatal error:  out of memory.\n");
  244.                   fatal_error=TRUE;
  245.                 }
  246.               else
  247.                 {
  248.                   max_x=2*num_columns;
  249.                   max_x_plus_1=max_x+1;
  250.                   max_y=2*num_rows;
  251.                   max_y_plus_1=max_y+1;
  252.                   if ((computer_page
  253.                    =(char **) malloc(max_x_plus_1*sizeof(char *))) == NULL)
  254.                     {
  255.                       printf("     Fatal error:  out of memory.\n");
  256.                       fatal_error=TRUE;
  257.                     }
  258.                   else
  259.                     {
  260.                       memory_allocated=TRUE;
  261.                       x=0;
  262.                       while ((memory_allocated) && (x < max_x_plus_1))
  263.                         if ((computer_page[x]
  264.                          =(char *) malloc(max_y_plus_1*sizeof(char))) == NULL)
  265.                           memory_allocated=FALSE;
  266.                         else
  267.                           x++;
  268.                       if (memory_allocated)
  269.                         {
  270.                           if ((user_page
  271.                            =(char **) malloc(max_x_plus_1*sizeof(char *)))
  272.                            == NULL)
  273.                             {
  274.                               printf("     Fatal error:  out of memory.\n");
  275.                               fatal_error=TRUE;
  276.                             }
  277.                           else
  278.                             {
  279.                               x=0;
  280.                               while ((memory_allocated) && (x < max_x_plus_1))
  281.                                 if ((user_page[x]
  282.                                  =(char *) malloc(max_y_plus_1*sizeof(char))) 
  283.                                  == NULL)
  284.                                   memory_allocated=FALSE;
  285.                                 else
  286.                                   x++;
  287.                               if (memory_allocated)
  288.                                 {
  289.                                   printf(
  290. "\n     While the maze is being generated, a spinning cursor is displayed:  ");
  291.                                   generate_maze(num_columns,num_rows,
  292.                                    num_rooms_in_maze,max_x,max_y,computer_page,
  293.                                    stack,&seed[0]);
  294.                                   registerbgidriver(EGAVGA_driver);
  295.                                   /*
  296.                                      See the Borland documentation on the
  297.                                      utilities "BINOBJ" and "TLIB" for 
  298.                                      information on how to link "EGAVGA.BGI"
  299.                                      into a program from "GRAPHICS.LIB".
  300.                                   */
  301.                                   GraphDriver=GRAPHICS_DRIVER;
  302.                                   GraphMode=GRAPHICS_MODE;
  303.                                   initgraph(&GraphDriver,&GraphMode,"");
  304.                                   ErrorCode=graphresult();
  305.                                   if (ErrorCode == 0)
  306.                                     {
  307.                                       getpalette(&palette);
  308.                                       for (color_num=0; 
  309.                                        color_num < (NUM_COLORS-3);
  310.                                        color_num++)
  311.                                         { /* evenly spaced shades of gray */
  312.                                           tint=(63*color_num)/(NUM_COLORS-3);
  313.                                           tint&=0xfc;
  314.                                           setrgbpalette(
  315.                                            palette.colors[color_num],
  316.                                            tint,tint,tint);
  317.                                         }
  318.                                       setrgbpalette(
  319.                                        palette.colors[BACKOUT_COLOR],
  320.                                        0xfc,0xfc,0);
  321.                                       setrgbpalette(
  322.                                        palette.colors[ADVANCE_COLOR],
  323.                                        0,0xfc,0);
  324.                                       setrgbpalette(
  325.                                        palette.colors[SOLUTION_COLOR],
  326.                                        0xfc,0,0);
  327.                                       settextjustify(CENTER_TEXT,BOTTOM_TEXT);
  328.                                       settextstyle(DEFAULT_FONT,HORIZ_DIR,0);
  329.                                       setcolor(NUM_COLORS-4);
  330.                                       outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  331.                                       "Arrows - Move    S - Solve    Q - Quit");
  332.                                       get_corners(tilt);
  333.                                       display_maze(num_columns,num_rows,max_x,
  334.                                        max_y,computer_page);
  335.                                       let_user_try_to_solve(&response,num_rows,
  336.                                        num_columns,max_x,max_y,computer_page,
  337.                                        user_page);
  338.                                       if ((response == (int) 's')
  339.                                       ||  (response == (int) 'S'))
  340.                                         {
  341.                                           display_solution(num_columns,
  342.                                            num_rows,max_x,max_y,computer_page);
  343.                                           setcolor(NUM_COLORS-4);
  344.                                           outtextxy(NUM_X_PIXELS/2,
  345.                                            NUM_Y_PIXELS-1,
  346.                                            "Press a key to continue.");
  347.                                           response=getch();
  348.                                           if (response == 0)
  349.                                             response=getch();
  350.                                         }
  351.                                       closegraph();
  352.                                     }
  353.                                   else
  354.                                     {
  355.                                       printf("     Fatal error:  %s\n",
  356.                                        grapherrormsg(ErrorCode));
  357.                                       fatal_error=TRUE;
  358.                                     }
  359.                                   for (x=max_x; x >= 0; x--)
  360.                                     free((void *) user_page[x]);
  361.                                 }
  362.                               else
  363.                                 while (x > 0)
  364.                                   free((void *) user_page[--x]);
  365.                               free((void *) user_page);
  366.                             }
  367.                           for (x=max_x; x >= 0; x--)
  368.                             free((void *) computer_page[x]);
  369.                         }
  370.                       else
  371.                         while (x > 0)
  372.                           free((void *) computer_page[--x]);
  373.                       free((void *) computer_page);
  374.                     }
  375.                   free((void *) stack);
  376.                 }
  377.             }
  378.         }
  379.       while ((! fatal_error) && (user_still_interested));
  380.       if (! fatal_error)
  381.         put_defaults(argv[0],default_num_columns,default_tilt,
  382.          &default_seed[0]);
  383.       return;
  384.     }
  385.  
  386. static void get_defaults(
  387.   char   *argv,
  388.   int    *default_num_columns,
  389.   double *default_tilt,
  390.   char   *default_seed)
  391.     {
  392.       register int  arg_index;
  393.       static   char *arg_ptr;
  394.                FILE *defaults;
  395.       static   char file_name [256];
  396.       static   int  last_period_index;
  397.       static   char line [256];
  398.       static   char *line_ptr;
  399.       static   int  num_assigned;
  400.       static   int  seed_length;
  401.       static   char *seed_ptr;
  402.  
  403.       arg_index=0;
  404.       arg_ptr=argv;
  405.       last_period_index=-1;
  406.       while ((*arg_ptr) && (arg_index < 252))
  407.         {
  408.           if (*arg_ptr == '.')
  409.             last_period_index=arg_index;
  410.           file_name[arg_index++]=*(arg_ptr++);
  411.         }
  412.       if ((*arg_ptr) || (last_period_index < 0))
  413.         {
  414.           *default_num_columns=30;
  415.           *default_tilt=(double) 30.0;
  416.           default_seed[0]='1';
  417.           default_seed[1]='\0';
  418.         }
  419.       else
  420.         {
  421.           file_name[++last_period_index]='I';
  422.           file_name[++last_period_index]='N';
  423.           file_name[++last_period_index]='I';
  424.           file_name[++last_period_index]='\0';
  425.           if ((defaults=fopen(&file_name[0],"r")) == NULL)
  426.             {
  427.               *default_num_columns=30;
  428.               *default_tilt=(double) 30.0;
  429.               default_seed[0]='1';
  430.               default_seed[1]='\0';
  431.             }
  432.           else
  433.             {
  434.               fgets(&line[0],256,defaults);
  435.               line_ptr=&line[0];
  436.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  437.                 line_ptr++;
  438.               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  439.                 *default_num_columns=30;
  440.               else
  441.                 {
  442.                   num_assigned=sscanf(line_ptr,"%d",default_num_columns);
  443.                   if ((num_assigned == 0) || (num_assigned == EOF))
  444.                     *default_num_columns=30;
  445.                 }
  446.               fgets(&line[0],256,defaults);
  447.               line_ptr=&line[0];
  448.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  449.                 line_ptr++;
  450.               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  451.                 *default_tilt=(double) 30.0;
  452.               else
  453.                 {
  454.                   num_assigned=sscanf(line_ptr,"%lf",default_tilt);
  455.                   if ((num_assigned == 0) || (num_assigned == EOF))
  456.                     *default_tilt=(double) 30.0;
  457.                 }
  458.               fgets(&line[0],256,defaults);
  459.               line_ptr=&line[0];
  460.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  461.                 line_ptr++;
  462.               seed_ptr=default_seed;
  463.               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  464.                 *(seed_ptr++)='1';
  465.               else
  466.                 {
  467.                   seed_length=0;
  468.                   while ((seed_length < 8)
  469.                   &&     (*line_ptr)
  470.                   &&     (*line_ptr != '\n')) 
  471.                     {
  472.                       *(seed_ptr++)=*(line_ptr++);
  473.                       seed_length++;
  474.                     }
  475.                 }
  476.               *seed_ptr='\0';
  477.               fclose(defaults);
  478.             }
  479.         }
  480.       return;
  481.     }
  482.  
  483. void interrupt new_critical_error_handler()
  484.     {
  485.       file_opened=FALSE;
  486.       return;
  487.     }
  488.  
  489. static void put_defaults(
  490.   char   *argv,
  491.   int    num_columns,
  492.   double tilt,
  493.   char   *seed)
  494.     {
  495.       static int  arg_index;
  496.       static char *arg_ptr;
  497.              FILE *defaults;
  498.       static char file_name [256];
  499.       static int  last_period_index;
  500.  
  501.       arg_index=0;
  502.       arg_ptr=argv;
  503.       last_period_index=-1;
  504.       while ((*arg_ptr) && (arg_index < 252))
  505.         {
  506.           if (*arg_ptr == '.')
  507.             last_period_index=arg_index;
  508.           file_name[arg_index++]=*(arg_ptr++);
  509.         }
  510.       if ((*arg_ptr == '\0') && (last_period_index >= 0))
  511.         {
  512.           file_name[++last_period_index]='I';
  513.           file_name[++last_period_index]='N';
  514.           file_name[++last_period_index]='I';
  515.           file_name[++last_period_index]='\0';
  516.           old_critical_error_handler=getvect(0x24);
  517.           setvect(0x24,new_critical_error_handler);
  518.           file_opened=TRUE;
  519.           if ((defaults=fopen(&file_name[0],"w")) != NULL)
  520.             {
  521.               setvect(0x24,old_critical_error_handler);
  522.               if (file_opened)
  523.                 {
  524.                   fprintf(defaults,"%d\n%lf\n%s\n",num_columns,tilt,seed);
  525.                   fclose(defaults);
  526.                 }
  527.             }
  528.           else 
  529.             setvect(0x24,old_critical_error_handler);           
  530.         }
  531.       return;
  532.     }
  533.  
  534. static void get_corners(
  535.   double tilt)
  536.     {
  537.       static   double cos_tilt;
  538.       static   int    i;
  539.       register int    j;
  540.       register int    k;
  541.       static   double pixels_per_unit;
  542.       static   double radians;
  543.       static   double radians_per_degree;
  544.       static   double sin_tilt;
  545.       static   double x;
  546.       static   double x_base [2];
  547.       static   double x_eye;
  548.       static   double x_prime;
  549.       static   double x_prime_max;
  550.       static   double y;
  551.       static   double y_base [2];
  552.       static   double y_center;
  553.       static   double y_offset;
  554.       static   double y_out_max;
  555.       static   double y_prime;
  556.       static   double y_prime_max;
  557.       static   double y_prime_min;
  558.       static   double z;
  559.       static   double z_base [2];
  560.       static   double z_center;
  561.       static   double z_offset;
  562.       static   double z_out_max;
  563.       static   double z_prime;
  564.       static   double z_prime_max;
  565.       static   double z_prime_min;
  566.  
  567.       x_base[0]=(double) X_PIXEL_MIN;
  568.       x_base[1]=(double) X_PIXEL_MAX;
  569.       y_base[0]=(double) Y_PIXEL_MIN;
  570.       y_base[1]=(double) Y_PIXEL_MAX;
  571.       z_base[0]=(double) 0.0;
  572.       z_base[1]=(double) ROOM_HEIGHT_IN_Y_PIXELS;
  573.       radians_per_degree=atan(1.0)/45.0;
  574.       radians=tilt*radians_per_degree;
  575.       cos_tilt=cos(radians);
  576.       sin_tilt=sin(radians);
  577.       x=x_base[0];
  578.       y=y_base[0];
  579.       z=z_base[0];
  580.       y_prime_min=x;
  581.       x_prime_max=y*cos_tilt+z*sin_tilt;
  582.       z_prime_min=-y*sin_tilt+z*cos_tilt;
  583.       y_prime_max=y_prime_min;
  584.       z_prime_max=z_prime_min;
  585.       for (i=0; i <= 1; i++)
  586.         for (j=0; j <= 1; j++)
  587.           for (k=0; k <= 1; k++)
  588.             {
  589.               x=x_base[k];
  590.               y=y_base[j];
  591.               z=z_base[i];
  592.               y_prime=x;
  593.               if (y_prime > y_prime_max)
  594.                 y_prime_max=y_prime;
  595.               else
  596.                 {
  597.                   if (y_prime < y_prime_min)
  598.                     y_prime_min=y_prime;
  599.                 }
  600.               x_prime=y*cos_tilt+z*sin_tilt;
  601.               if (x_prime > x_prime_max)
  602.                 x_prime_max=x_prime;
  603.               z_prime=-y*sin_tilt+z*cos_tilt;
  604.               if (z_prime > z_prime_max)
  605.                 z_prime_max=z_prime;
  606.               else
  607.                 {
  608.                   if (z_prime < z_prime_min)
  609.                     z_prime_min=z_prime;
  610.                 }
  611.             }
  612.       if ((y_prime_max-y_prime_min) > (z_prime_max-z_prime_min))
  613.         x_eye=1.1*(y_prime_max-y_prime_min)+x_prime_max;
  614.       else
  615.         x_eye=1.1*(z_prime_max-z_prime_min)+x_prime_max;
  616.       /* 1.1 for slight "fish-eye" */
  617.       y_center=(y_prime_max+y_prime_min)/2.0;
  618.       z_center=(z_prime_max+z_prime_min)/2.0;
  619.       y_out_max=(double) (X_PIXEL_MAX-X_PIXEL_MIN);
  620.       z_out_max=(double) (Y_PIXEL_MAX-Y_PIXEL_MIN);
  621.       if (z_out_max*(y_prime_max-y_prime_min)
  622.        > y_out_max*(z_prime_max-z_prime_min))
  623.         {
  624.           pixels_per_unit=y_out_max/(y_prime_max-y_prime_min);
  625.           y_offset=0.0;
  626.           z_offset=-(z_out_max-pixels_per_unit*(z_prime_max-z_prime_min))/2.0;
  627.         }
  628.       else
  629.         if (z_out_max*(y_prime_max-y_prime_min)
  630.          < y_out_max*(z_prime_max-z_prime_min))
  631.           {
  632.             pixels_per_unit=z_out_max/(z_prime_max-z_prime_min);
  633.             y_offset=(y_out_max
  634.              -pixels_per_unit*(y_prime_max-y_prime_min))/2.0;
  635.             z_offset=0.0;
  636.           }
  637.         else
  638.           {
  639.             pixels_per_unit=1.0;
  640.             y_offset=y_out_max/2.0;
  641.             z_offset=-z_out_max/2.0;
  642.           }
  643.       for (i=0; i <= 1; i++)
  644.         for (j=0; j <= 1; j++)
  645.           for (k=0; k <= 1; k++)
  646.             {
  647.               x=x_base[k];
  648.               y=y_base[j];
  649.               z=z_base[i];
  650.               y_prime=x;
  651.               x_prime=y*cos_tilt+z*sin_tilt;
  652.               z_prime=-y*sin_tilt+z*cos_tilt;
  653.               x=x_prime;
  654.               y=y_prime;
  655.               z=z_prime;
  656.               y_prime=y_center+(y-y_center)*(x_eye-x_prime_max)/(x_eye-x);
  657.               z_prime=z_center+(z-z_center)*(x_eye-x_prime_max)/(x_eye-x);
  658.               y=y_prime;
  659.               z=z_prime;
  660.               x_corner[k][j][i]=X_PIXEL_MIN
  661.                +(int) (y_offset+pixels_per_unit*(y-y_prime_min));
  662.               y_corner[k][j][i]=Y_PIXEL_MIN
  663.                +(int) (z_offset+z_out_max-pixels_per_unit*(z-z_prime_min));
  664.             }
  665.       return;
  666.     }
  667.  
  668. static int substitution_high [100] =
  669.              { 4,1,2,8,8,9,9,6,5,7,2,1,2,9,8,8,6,3,5,1,9,5,4,4,9,8,6,0,8,0,
  670.                6,0,2,4,1,9,2,0,7,4,7,3,0,0,2,6,8,9,4,0,8,3,2,3,2,5,2,4,6,9,
  671.                7,9,1,3,5,7,1,1,4,5,8,1,6,0,5,7,8,2,3,3,7,3,5,1,7,5,4,0,3,6,
  672.                3,7,7,1,9,4,0,5,6,6
  673.              };
  674. static int substitution_low [100] =
  675.              { 1,2,2,1,5,5,4,6,4,6,4,4,5,6,6,3,0,9,6,5,7,2,0,9,3,4,2,3,9,1,
  676.                9,9,9,3,8,9,3,4,1,5,0,5,2,7,0,8,8,0,4,5,0,3,6,8,1,7,8,8,7,1,
  677.                3,2,7,7,1,8,0,3,7,5,2,6,4,0,9,9,7,7,4,6,2,0,0,1,7,3,6,6,1,1,
  678.                2,4,5,9,8,2,8,8,3,5
  679.              };
  680. static void hash(
  681.   int *counter_0,
  682.   int *counter_1,
  683.   int *counter_2,
  684.   int *counter_3,
  685.   int *counter_4,
  686.   int *counter_5,
  687.   int *counter_6,
  688.   int *counter_7)
  689.     {
  690.       register int iteration;
  691.       static   int seed_0;
  692.       static   int seed_1;
  693.       static   int seed_2;
  694.       static   int seed_3;
  695.       static   int seed_4;
  696.       static   int seed_5;
  697.       static   int seed_6;
  698.       static   int seed_7;
  699.       register int substitution_index;
  700.       static   int tem_0;
  701.       static   int tem_1;
  702.       static   int tem_2;
  703.  
  704.       seed_0=(*counter_0);
  705.       seed_1=(*counter_1);
  706.       seed_2=(*counter_2);
  707.       seed_3=(*counter_3);
  708.       seed_4=(*counter_4);
  709.       seed_5=(*counter_5);
  710.       seed_6=(*counter_6);
  711.       seed_7=(*counter_7);
  712.       for (iteration=1; iteration <= 8; iteration++)
  713.         {
  714.           substitution_index=10*seed_1+seed_0;
  715.           tem_0=substitution_low[substitution_index];
  716.           tem_1=substitution_high[substitution_index];
  717.           substitution_index=10*seed_3+seed_2;
  718.           seed_0=substitution_low[substitution_index];
  719.           tem_2=substitution_high[substitution_index];
  720.           substitution_index=10*seed_5+seed_4;
  721.           seed_2=substitution_low[substitution_index];
  722.           seed_1=substitution_high[substitution_index];
  723.           substitution_index=10*seed_7+seed_6;
  724.           seed_5=substitution_low[substitution_index];
  725.           seed_7=substitution_high[substitution_index];
  726.           seed_3=tem_0;
  727.           seed_6=tem_1;
  728.           seed_4=tem_2;
  729.         }
  730.       (*counter_0)=seed_0;
  731.       (*counter_1)=seed_1;
  732.       (*counter_2)=seed_2;
  733.       (*counter_3)=seed_3;
  734.       (*counter_4)=seed_4;
  735.       (*counter_5)=seed_5;
  736.       (*counter_6)=seed_6;
  737.       (*counter_7)=seed_7;
  738.       return;
  739.     }
  740.  
  741. static void increment(
  742.   int *counter_0,
  743.   int *counter_1,
  744.   int *counter_2,
  745.   int *counter_3,
  746.   int *counter_4,
  747.   int *counter_5,
  748.   int *counter_6,
  749.   int *counter_7)
  750.     {
  751.       register tem;
  752.  
  753.       tem=(*counter_0)+1;
  754.       if (tem <= 9)
  755.         (*counter_0)=tem;
  756.       else
  757.         {
  758.           (*counter_0)=0;
  759.           tem=(*counter_1)+1;
  760.           if (tem <= 9)
  761.             (*counter_1)=tem;
  762.           else
  763.             {
  764.               (*counter_1)=0;
  765.               tem=(*counter_2)+1;
  766.               if (tem <= 9)
  767.                 (*counter_2)=tem;
  768.               else
  769.                 {
  770.                   (*counter_2)=0;
  771.                   tem=(*counter_3)+1;
  772.                   if (tem <= 9)
  773.                     (*counter_3)=tem;
  774.                   else
  775.                     {
  776.                       (*counter_3)=0;
  777.                       tem=(*counter_4)+1;
  778.                       if (tem <= 9)
  779.                         (*counter_4)=tem;
  780.                       else
  781.                         {
  782.                           (*counter_4)=0;
  783.                           tem=(*counter_5)+1;
  784.                           if (tem <= 9)
  785.                             (*counter_5)=tem;
  786.                           else
  787.                             {
  788.                               (*counter_5)=0;
  789.                               tem=(*counter_6)+1;
  790.                               if (tem <= 9)
  791.                                 (*counter_6)=tem;
  792.                               else
  793.                                 {
  794.                                   (*counter_6)=0;
  795.                                   tem=(*counter_7)+1;
  796.                                   if (tem <= 9)
  797.                                     (*counter_7)=tem;
  798.                                   else
  799.                                     (*counter_7)=0;
  800.                                 }
  801.                             }
  802.                         }
  803.                     }
  804.                 }
  805.             }
  806.         }
  807.       return;
  808.     }
  809.  
  810. static void get_cursor(
  811.   unsigned char *cursor_row,
  812.   unsigned char *cursor_column,
  813.   unsigned char *cursor_start,
  814.   unsigned char *cursor_stop)
  815.     {
  816.       static union REGS in;
  817.       static union REGS out;
  818.  
  819.       in.h.ah=(unsigned char) 3;
  820.       in.h.bh=(unsigned char) 0;
  821.       int86(0x10,&in,&out);
  822.       *cursor_row=out.h.dh;
  823.       *cursor_column=out.h.dl;
  824.       *cursor_start=out.h.ch;
  825.       *cursor_stop=out.h.cl;
  826.       return;
  827.     }
  828.  
  829. static void set_cursor_position(
  830.   unsigned char cursor_row,
  831.   unsigned char cursor_column)
  832.     {
  833.       static union REGS in;
  834.       static union REGS out;
  835.  
  836.       in.h.ah=(unsigned char) 2;
  837.       in.h.dh=cursor_row;
  838.       in.h.dl=cursor_column;
  839.       int86(0x10,&in,&out);
  840.       return;
  841.     }
  842.  
  843. static void set_cursor_size(
  844.   unsigned char cursor_start,
  845.   unsigned char cursor_stop)
  846.     {
  847.       static union REGS in;
  848.       static union REGS out;
  849.  
  850.       in.h.ah=(unsigned char) 1;
  851.       in.h.ch=cursor_start;
  852.       in.h.cl=cursor_stop;
  853.       int86(0x10,&in,&out);
  854.       return;
  855.     }
  856.  
  857. static void titillate()
  858.     {
  859.       set_cursor_position(cursor_row,cursor_column);
  860.       titillator_index++;
  861.       if (titillator_index > 3)
  862.         titillator_index=0;
  863.       putchar((int) titillator[titillator_index]);
  864.       return;
  865.     }
  866.  
  867. static void solve_maze(
  868.   int       max_x,
  869.   int       max_y,
  870.   int       *num_rooms_in_solution,
  871.   int       *adjacency,
  872.   char      **page,
  873.   stack_rec *stack)
  874.     {
  875.       static int delta_index;
  876.       static int passage_found;
  877.       static int stack_head;
  878.       static int x;
  879.       static int x_next;
  880.       static int y;
  881.       static int y_next;
  882.  
  883.       *num_rooms_in_solution=1;
  884.       *adjacency=0;
  885.       x=1;
  886.       y=1;
  887.       stack_head=-1;
  888.       page[x][y]='S';
  889.       do
  890.         {
  891.           delta_index=0;
  892.           passage_found=FALSE;
  893.           do
  894.             {
  895.               while ((delta_index < 4) && (! passage_found))
  896.                 {
  897.                   x_next=x+delta_x[delta_index][0];
  898.                   y_next=y+delta_y[delta_index][0];
  899.                   if (page[x_next][y_next] == ' ')
  900.                     passage_found=TRUE;
  901.                   else
  902.                     delta_index++;
  903.                 }
  904.               if (! passage_found)
  905.                 {
  906.                   delta_index=(int) (stack[stack_head].index_1);
  907.                   page[x][y]=' ';
  908.                   x-=delta_x[delta_index][0];
  909.                   y-=delta_y[delta_index][0];
  910.                   page[x][y]=' ';
  911.                   x-=delta_x[delta_index][0];
  912.                   y-=delta_y[delta_index][0];
  913.                   stack_head--;
  914.                   delta_index++;
  915.                 }
  916.             }
  917.           while (! passage_found);
  918.           page[x_next][y_next]='S';
  919.           x_next+=delta_x[delta_index][0];
  920.           y_next+=delta_y[delta_index][0];
  921.           if (y_next <= max_y)
  922.             {
  923.               stack_head++;
  924.               stack[stack_head].index_1=(char) delta_index;
  925.               page[x_next][y_next]='S';
  926.               x=x_next;
  927.               y=y_next;
  928.             }
  929.         }
  930.       while (y_next < max_y);
  931.       x=max_x-1;
  932.       y=max_y-1;
  933.       *adjacency=0;
  934.       while (stack_head >= 0)
  935.         {
  936.           for (delta_index=0; delta_index < 4; delta_index++)
  937.             {
  938.               x_next=x+delta_x[delta_index][0];
  939.               y_next=y+delta_y[delta_index][0];
  940.               if (page[x_next][y_next] != 'S')
  941.                 {
  942.                   if (page[x_next][y_next] == 'W')
  943.                     {
  944.                       x_next+=delta_x[delta_index][0];
  945.                       y_next+=delta_y[delta_index][0];
  946.                       if (x_next < 0)
  947.                         (*adjacency)++;
  948.                       else
  949.                         if (x_next > max_x)
  950.                           (*adjacency)++;
  951.                         else
  952.                           if (y_next < 0)
  953.                             (*adjacency)++;
  954.                           else
  955.                             if (y_next > max_y)
  956.                               (*adjacency)++;
  957.                             else
  958.                               {
  959.                                 if (page[x_next][y_next] == 'S')
  960.                                   (*adjacency)++;
  961.                               }
  962.                     }
  963.                 }
  964.             }
  965.           x-=(2*delta_x[stack[stack_head].index_1][0]);
  966.           y-=(2*delta_y[stack[stack_head].index_1][0]);
  967.           stack_head--;
  968.           (*num_rooms_in_solution)++;
  969.         }
  970.       for (delta_index=0; delta_index < 4; delta_index++)
  971.         {
  972.           x_next=x+delta_x[delta_index][0];
  973.           y_next=y+delta_y[delta_index][0];
  974.           if (page[x_next][y_next] != ' ')
  975.             {
  976.               if (page[x_next][y_next] == 'W')
  977.                 {
  978.                   x_next+=delta_x[delta_index][0];
  979.                   y_next+=delta_y[delta_index][0];
  980.                   if (x_next < 0)
  981.                     (*adjacency)++;
  982.                   else
  983.                     if (x_next > max_x)
  984.                       (*adjacency)++;
  985.                     else
  986.                       if (y_next < 0)
  987.                         (*adjacency)++;
  988.                       else
  989.                         if (y_next > max_y)
  990.                           (*adjacency)++;
  991.                         else
  992.                           {
  993.                             if (page[x_next][y_next] == 'S')
  994.                               (*adjacency)++;
  995.                           }
  996.                 }
  997.             }
  998.         }
  999.       return;
  1000.     }
  1001.  
  1002. static void generate_maze(
  1003.   int       num_columns,
  1004.   int       num_rows,
  1005.   int       num_rooms_in_maze,
  1006.   int       max_x,
  1007.   int       max_y,
  1008.   char      **page,
  1009.   stack_rec *stack,
  1010.   char      *seed_ptr)
  1011.     {
  1012.       static   int           adjacency;
  1013.       static   int           age;
  1014.       static   int           counter_0;
  1015.       static   int           counter_1;
  1016.       static   int           counter_2;
  1017.       static   int           counter_3;
  1018.       static   int           counter_4;
  1019.       static   int           counter_5;
  1020.       static   int           counter_6;
  1021.       static   int           counter_7;
  1022.       static   int           delta_index_1a;
  1023.       static   int           delta_index_1b;
  1024.       static   int           delta_index_1c;
  1025.       static   int           delta_index_1d;
  1026.       static   int           delta_index_2;
  1027.       static   int           digit;
  1028.       static   int           digit_num;
  1029.       static   int           num_rooms_in_solution;
  1030.       static   int           passage_found;
  1031.       static   int           r_n [8];
  1032.       static   int           r_n_index_1;
  1033.       static   int           r_n_index_2;
  1034.       static   int           search_complete;
  1035.       static   int           stack_head;
  1036.       static   int           sum;
  1037.       static   int           tem_int;
  1038.       static   int           trial_num_mod_10;
  1039.       static   int           x;
  1040.       register int           x_next;
  1041.       static   int           y;
  1042.       register int           y_next;
  1043.  
  1044.       while ((*seed_ptr == ' ')
  1045.       ||     (*seed_ptr == (char) 9))
  1046.         seed_ptr++;
  1047.       r_n_index_1=0;
  1048.       while ((r_n_index_1 < 8) && (*seed_ptr) && (*seed_ptr != '\n'))
  1049.         r_n[r_n_index_1++]=(int) (*(seed_ptr++) % 10);
  1050.       r_n_index_2=7;
  1051.       while (r_n_index_1 > 0)
  1052.         {
  1053.            r_n_index_1--;
  1054.            r_n[r_n_index_2]=r_n[r_n_index_1];
  1055.            r_n_index_2--;
  1056.         }
  1057.       while (r_n_index_2 >= 0)
  1058.         {
  1059.           r_n[r_n_index_2]=8;
  1060.           r_n_index_2--;
  1061.         }
  1062.       counter_0=r_n[0];
  1063.       counter_1=r_n[1];
  1064.       counter_2=r_n[2];
  1065.       counter_3=r_n[3];
  1066.       counter_4=r_n[4];
  1067.       counter_5=r_n[5];
  1068.       counter_6=r_n[6];
  1069.       counter_7=r_n[7];
  1070.       hash(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,&counter_5,
  1071.        &counter_6,&counter_7);
  1072.       delta_x[0][0]=-1;
  1073.       delta_y[0][0]=0;
  1074.       delta_x[1][0]=0;
  1075.       delta_y[1][0]=1;
  1076.       delta_x[2][0]=1;
  1077.       delta_y[2][0]=0;
  1078.       delta_x[3][0]=0;
  1079.       delta_y[3][0]=-1;
  1080.       delta_index_2=0;
  1081.       for (delta_index_1a=0; delta_index_1a < 4; ++delta_index_1a)
  1082.         for (delta_index_1b=0; delta_index_1b < 4; ++delta_index_1b)
  1083.           if (delta_index_1a != delta_index_1b)
  1084.             for (delta_index_1c=0; delta_index_1c < 4; ++delta_index_1c)
  1085.               if ((delta_index_1a != delta_index_1c)
  1086.               &&  (delta_index_1b != delta_index_1c))
  1087.                 for (delta_index_1d=0; delta_index_1d < 4; ++delta_index_1d)
  1088.                   if ((delta_index_1a != delta_index_1d)
  1089.                   &&  (delta_index_1b != delta_index_1d)
  1090.                   &&  (delta_index_1c != delta_index_1d))
  1091.                     {
  1092.                       delta_x[delta_index_1a][delta_index_2]=delta_x[0][0];
  1093.                       delta_y[delta_index_1a][delta_index_2]=delta_y[0][0];
  1094.                       delta_x[delta_index_1b][delta_index_2]=delta_x[1][0];
  1095.                       delta_y[delta_index_1b][delta_index_2]=delta_y[1][0];
  1096.                       delta_x[delta_index_1c][delta_index_2]=delta_x[2][0];
  1097.                       delta_y[delta_index_1c][delta_index_2]=delta_y[2][0];
  1098.                       delta_x[delta_index_1d][delta_index_2]=delta_x[3][0];
  1099.                       delta_y[delta_index_1d][delta_index_2]=delta_y[3][0];
  1100.                       delta_index_2++;
  1101.                     };
  1102.       get_cursor(&cursor_row,&cursor_column,&cursor_start,&cursor_stop);
  1103.       set_cursor_size((unsigned char) 32,(unsigned char) 32);
  1104.       titillator_index=0;
  1105.       age=3;
  1106.       trial_num_mod_10=0;
  1107.       do
  1108.         {
  1109.           titillate();
  1110.           for (x=0; x <= max_x; ++x)
  1111.             for (y=0; y <= max_y; ++y)
  1112.               page[x][y]='W';
  1113.           r_n[0]=counter_0+1;
  1114.           r_n[1]=counter_1+1;
  1115.           r_n[2]=counter_2+1;
  1116.           r_n[3]=counter_3+1;
  1117.           r_n[4]=counter_4+1;
  1118.           r_n[5]=counter_5+1;
  1119.           r_n[6]=counter_6+1;
  1120.           r_n[7]=counter_7+1;
  1121.           sum=0;
  1122.           for (digit_num=1; digit_num <= 3; ++digit_num)
  1123.             {
  1124.               digit=r_n[0];
  1125.               r_n_index_1=0;
  1126.               for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
  1127.                 {
  1128.                   tem_int=r_n[r_n_index_2];
  1129.                   r_n[r_n_index_1]=tem_int;
  1130.                   digit+=tem_int;
  1131.                   if (digit >= 29)
  1132.                      digit-=29;
  1133.                   r_n_index_1=r_n_index_2;
  1134.                 }
  1135.               r_n[7]=digit;
  1136.               sum=29*sum+digit;
  1137.             }
  1138.           x=2*(sum % num_columns)+1;
  1139.           sum=0;
  1140.           for (digit_num=1; digit_num <= 3; ++digit_num)
  1141.             {
  1142.               digit=r_n[0];
  1143.               r_n_index_1=0;
  1144.               for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
  1145.                 {
  1146.                   tem_int=r_n[r_n_index_2];
  1147.                   r_n[r_n_index_1]=tem_int;
  1148.                   digit+=tem_int;
  1149.                   if (digit >= 29)
  1150.                      digit-=29;
  1151.                   r_n_index_1=r_n_index_2;
  1152.                 }
  1153.               r_n[7]=digit;
  1154.               sum=29*sum+digit;
  1155.             }
  1156.           y=2*(sum % num_rows)+1;
  1157.           page[x][y]=' ';
  1158.           stack_head=-1;
  1159.           do
  1160.             {
  1161.               delta_index_1a=0;
  1162.               do
  1163.                 {
  1164.                   delta_index_2=r_n[0];
  1165.                   r_n_index_1=0;
  1166.                   r_n_index_2=1;
  1167.                   while (r_n_index_2 < 8)
  1168.                     {
  1169.                       tem_int=r_n[r_n_index_2];
  1170.                       r_n[r_n_index_1]=tem_int;
  1171.                       delta_index_2+=tem_int;
  1172.                       if (delta_index_2 >= 29)
  1173.                         delta_index_2-=29;
  1174.                       r_n_index_1=r_n_index_2;
  1175.                       r_n_index_2++;
  1176.                     }
  1177.                   r_n[7]=delta_index_2;
  1178.                 }
  1179.               while (delta_index_2 >= 24);
  1180.               passage_found=FALSE;
  1181.               search_complete=FALSE;
  1182.               while (! search_complete)
  1183.                 {
  1184.                   while ((delta_index_1a < 4) && (! passage_found))
  1185.                     {
  1186.                       x_next=x+2*delta_x[delta_index_1a][delta_index_2];
  1187.                       if (x_next <= 0)
  1188.                         delta_index_1a++;
  1189.                       else
  1190.                         if (x_next > max_x)
  1191.                           delta_index_1a++;
  1192.                         else
  1193.                           {
  1194.                             y_next=y+2*delta_y[delta_index_1a][delta_index_2];
  1195.                             if (y_next <= 0)
  1196.                               delta_index_1a++;
  1197.                             else
  1198.                               if (y_next > max_y)
  1199.                                 delta_index_1a++;
  1200.                               else
  1201.                                 if (page[x_next][y_next] == 'W')
  1202.                                   passage_found=TRUE;
  1203.                                 else
  1204.                                   delta_index_1a++;
  1205.                           }
  1206.                     }
  1207.                   if (! passage_found)
  1208.                     {
  1209.                       if (stack_head >= 0)
  1210.                         {
  1211.                           delta_index_1a=(int) (stack[stack_head].index_1);
  1212.                           delta_index_2=stack[stack_head].index_2;
  1213.                           x-=2*delta_x[delta_index_1a][delta_index_2];
  1214.                           y-=2*delta_y[delta_index_1a][delta_index_2];
  1215.                           stack_head--;
  1216.                           delta_index_1a++;
  1217.                         }
  1218.                     }
  1219.                   search_complete=((passage_found)
  1220.                    || ((stack_head == -1) && (delta_index_1a >= 4)));
  1221.                 }
  1222.               if (passage_found)
  1223.                 {
  1224.                   stack_head++;
  1225.                   stack[stack_head].index_1=(char) delta_index_1a;
  1226.                   stack[stack_head].index_2=delta_index_2;
  1227.                   page[x_next][y_next]=' ';
  1228.                   page[(x+x_next)/2][(y+y_next)/2]=' ';
  1229.                   x=x_next;
  1230.                   y=y_next;
  1231.                 }
  1232.             }
  1233.           while (stack_head != -1);
  1234.           page[1][0]='S';
  1235.           page[max_x-1][max_y]=' ';
  1236.           solve_maze(max_x,max_y,&num_rooms_in_solution,&adjacency,page,stack);
  1237.           increment(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,
  1238.            &counter_5,&counter_6,&counter_7);
  1239.           trial_num_mod_10++;
  1240.           if (trial_num_mod_10 >= 10)
  1241.             {
  1242.               trial_num_mod_10=0;
  1243.               age++;
  1244.             }
  1245.         }
  1246.       while ((3*num_rooms_in_solution < num_rooms_in_maze)
  1247.       ||     (2*adjacency > age*num_rooms_in_solution));
  1248.       set_cursor_size(cursor_start,cursor_stop);
  1249.       return;
  1250.     }
  1251.  
  1252. static void output_wall(
  1253.   int num_columns,
  1254.   int x_out_left,
  1255.   int x_out_right,
  1256.   int y_pixel_floor_back,
  1257.   int y_pixel_floor_front,
  1258.   int y_pixel_top_back,
  1259.   int y_pixel_top_front,
  1260.   int x_pixel_floor_back_left_edge,
  1261.   int x_pixel_floor_back_right_edge,
  1262.   int x_pixel_top_back_left_edge,
  1263.   int x_pixel_top_back_right_edge,
  1264.   int x_pixel_floor_front_left_edge,
  1265.   int x_pixel_floor_front_right_edge,
  1266.   int x_pixel_top_front_left_edge,
  1267.   int x_pixel_top_front_right_edge)
  1268.     {
  1269.       static    corner_rec quadrilateral [4];
  1270.       static    int        x_pixel_floor_back_left;
  1271.       static    int        x_pixel_floor_back_right;
  1272.       static    int        x_pixel_floor_front_left;
  1273.       static    int        x_pixel_floor_front_right;
  1274.       static    int        x_pixel_top_back_left;
  1275.       static    int        x_pixel_top_back_right;
  1276.       static    int        x_pixel_top_front_left;
  1277.       static    int        x_pixel_top_front_right;
  1278.  
  1279.       x_pixel_floor_back_left
  1280.        =((int) (((long) x_out_left)
  1281.        *((long) (x_pixel_floor_back_right_edge
  1282.        -x_pixel_floor_back_left_edge))
  1283.        /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_columns+1))))
  1284.        +x_pixel_floor_back_left_edge;
  1285.       x_pixel_floor_back_right
  1286.        =((int) (((long) x_out_right)
  1287.        *((long) (x_pixel_floor_back_right_edge
  1288.        -x_pixel_floor_back_left_edge))
  1289.        /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_columns+1))))
  1290.        +x_pixel_floor_back_left_edge;
  1291.       x_pixel_floor_front_left
  1292.        =((int) (((long) x_out_left)
  1293.        *((long) (x_pixel_floor_front_right_edge
  1294.        -x_pixel_floor_front_left_edge))
  1295.        /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_columns+1))))
  1296.        +x_pixel_floor_front_left_edge;
  1297.       x_pixel_floor_front_right
  1298.        =((int) (((long) x_out_right)
  1299.        *((long) (x_pixel_floor_front_right_edge
  1300.        -x_pixel_floor_front_left_edge))
  1301.        /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_columns+1))))
  1302.        +x_pixel_floor_front_left_edge;
  1303.       x_pixel_top_back_left
  1304.        =((int) (((long) x_out_left)
  1305.        *((long) (x_pixel_top_back_right_edge
  1306.        -x_pixel_top_back_left_edge))
  1307.        /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_columns+1))))
  1308.        +x_pixel_top_back_left_edge;
  1309.       x_pixel_top_back_right
  1310.        =((int) (((long) x_out_right)
  1311.        *((long) (x_pixel_top_back_right_edge
  1312.        -x_pixel_top_back_left_edge))
  1313.        /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_columns+1))))
  1314.        +x_pixel_top_back_left_edge;
  1315.       x_pixel_top_front_left
  1316.        =((int) (((long) x_out_left)
  1317.        *((long) (x_pixel_top_front_right_edge
  1318.        -x_pixel_top_front_left_edge))
  1319.        /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_columns+1))))
  1320.        +x_pixel_top_front_left_edge;
  1321.       x_pixel_top_front_right
  1322.        =((int) (((long) x_out_right)
  1323.        *((long) (x_pixel_top_front_right_edge
  1324.        -x_pixel_top_front_left_edge))
  1325.        /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_columns+1))))
  1326.        +x_pixel_top_front_left_edge;
  1327.       if (2*(x_pixel_floor_back_left-x_pixel_floor_back_left_edge)
  1328.        > (x_pixel_floor_back_right_edge-x_pixel_floor_back_left_edge))
  1329.         {
  1330.           setcolor(LEFT_WALL_COLOR);
  1331.           setfillstyle(SOLID_FILL,LEFT_WALL_COLOR);
  1332.           quadrilateral[0].x=x_pixel_floor_back_left;
  1333.           quadrilateral[0].y=y_pixel_floor_back;
  1334.           quadrilateral[1].x=x_pixel_top_back_left;
  1335.           quadrilateral[1].y=y_pixel_top_back;
  1336.           quadrilateral[2].x=x_pixel_top_front_left;
  1337.           quadrilateral[2].y=y_pixel_top_front;
  1338.           quadrilateral[3].x=x_pixel_floor_front_left;
  1339.           quadrilateral[3].y=y_pixel_floor_front;
  1340.           fillpoly(4,&(quadrilateral[0].x));
  1341.         }
  1342.       if (2*(x_pixel_floor_back_right-x_pixel_floor_back_left_edge)
  1343.        < (x_pixel_floor_back_right_edge-x_pixel_floor_back_left_edge))
  1344.         {
  1345.           setcolor(RIGHT_WALL_COLOR);
  1346.           setfillstyle(SOLID_FILL,RIGHT_WALL_COLOR);
  1347.           quadrilateral[0].x=x_pixel_floor_back_right;
  1348.           quadrilateral[0].y=y_pixel_floor_back;
  1349.           quadrilateral[1].x=x_pixel_top_back_right;
  1350.           quadrilateral[1].y=y_pixel_top_back;
  1351.           quadrilateral[2].x=x_pixel_top_front_right;
  1352.           quadrilateral[2].y=y_pixel_top_front;
  1353.           quadrilateral[3].x=x_pixel_floor_front_right;
  1354.           quadrilateral[3].y=y_pixel_floor_front;
  1355.           fillpoly(4,&(quadrilateral[0].x));
  1356.         }
  1357.       setcolor(FRONT_WALL_COLOR);
  1358.       setfillstyle(SOLID_FILL,FRONT_WALL_COLOR);
  1359.       quadrilateral[0].x=x_pixel_floor_front_left;
  1360.       quadrilateral[0].y=y_pixel_floor_front;
  1361.       quadrilateral[1].x=x_pixel_floor_front_right;
  1362.       quadrilateral[1].y=y_pixel_floor_front;
  1363.       quadrilateral[2].x=x_pixel_top_front_right;
  1364.       quadrilateral[2].y=y_pixel_top_front;
  1365.       quadrilateral[3].x=x_pixel_top_front_left;
  1366.       quadrilateral[3].y=y_pixel_top_front;
  1367.       fillpoly(4,&(quadrilateral[0].x));
  1368.       setcolor(TOP_WALL_COLOR);
  1369.       setfillstyle(SOLID_FILL,TOP_WALL_COLOR);
  1370.       quadrilateral[0].x=x_pixel_top_front_left;
  1371.       quadrilateral[0].y=y_pixel_top_front;
  1372.       quadrilateral[1].x=x_pixel_top_front_right;
  1373.       quadrilateral[1].y=y_pixel_top_front;
  1374.       quadrilateral[2].x=x_pixel_top_back_right;
  1375.       quadrilateral[2].y=y_pixel_top_back;
  1376.       quadrilateral[3].x=x_pixel_top_back_left;
  1377.       quadrilateral[3].y=y_pixel_top_back;
  1378.       fillpoly(4,&(quadrilateral[0].x));
  1379.       return;
  1380.     }
  1381.  
  1382. static void display_maze(
  1383.   int  num_columns,
  1384.   int  num_rows,
  1385.   int  max_x,
  1386.   int  max_y,
  1387.   char **page)
  1388.   {
  1389.     static    char       current_char;
  1390.     static    char       previous_char;
  1391.     static    corner_rec quadrilateral [4];
  1392.     static    int        x;
  1393.     static    int        x_even;
  1394.     static    int        x_out_left;
  1395.     static    int        x_out_left_most;
  1396.     static    int        x_out_right;
  1397.     static    int        x_out_right_most;
  1398.     static    int        x_pixel_floor_back_left_edge;
  1399.     static    int        x_pixel_floor_back_right_edge;
  1400.     static    int        x_pixel_floor_front_left_edge;
  1401.     static    int        x_pixel_floor_front_right_edge;
  1402.     static    int        x_pixel_top_back_left_edge;
  1403.     static    int        x_pixel_top_back_right_edge;
  1404.     static    int        x_pixel_top_front_left_edge;
  1405.     static    int        x_pixel_top_front_right_edge;
  1406.     static    int        y;
  1407.     static    int        y_even;
  1408.     static    int        y_out_back;
  1409.     static    int        y_out_front;
  1410.     static    int        y_pixel_floor_back;
  1411.     static    int        y_pixel_floor_front;
  1412.     static    int        y_pixel_top_back;
  1413.     static    int        y_pixel_top_front;
  1414.  
  1415.     setlinestyle(SOLID_LINE,0xffff,NORM_WIDTH);
  1416.     setcolor(FLOOR_COLOR);
  1417.     setfillstyle(SOLID_FILL,FLOOR_COLOR);
  1418.     quadrilateral[0].x=x_corner[0][0][0];
  1419.     quadrilateral[0].y=y_corner[0][0][0];
  1420.     quadrilateral[1].x=x_corner[0][1][0];
  1421.     quadrilateral[1].y=y_corner[0][1][0];
  1422.     quadrilateral[2].x=x_corner[1][1][0];
  1423.     quadrilateral[2].y=y_corner[1][1][0];
  1424.     quadrilateral[3].x=x_corner[1][0][0];
  1425.     quadrilateral[3].y=y_corner[1][0][0];
  1426.     fillpoly(4,&(quadrilateral[0].x));
  1427.     y_even=TRUE;
  1428.     y_out_back=0;
  1429.     y_out_front=1;
  1430.     for (y=0; y <= max_y; y++)
  1431.       {
  1432.         y_pixel_floor_back
  1433.          =((int) ((long) y_out_back)
  1434.          *((long) (y_corner[1][1][0]-y_corner[1][0][0]))
  1435.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1436.          +y_corner[1][0][0];
  1437.         y_pixel_floor_front
  1438.          =((int) ((long) y_out_front)
  1439.          *((long) (y_corner[1][1][0]-y_corner[1][0][0]))
  1440.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1441.          +y_corner[1][0][0];
  1442.         y_pixel_top_back
  1443.          =((int) ((long) y_out_back)
  1444.          *((long) (y_corner[1][1][1]-y_corner[1][0][1]))
  1445.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1446.          +y_corner[1][0][1];
  1447.         y_pixel_top_front
  1448.          =((int) ((long) y_out_front)
  1449.          *((long) (y_corner[1][1][1]-y_corner[1][0][1]))
  1450.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1451.          +y_corner[1][0][1];
  1452.         x_pixel_floor_back_left_edge
  1453.          =((int) ((long) y_out_back)
  1454.          *((long) (x_corner[0][1][0]-x_corner[0][0][0]))
  1455.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1456.          +x_corner[0][0][0];
  1457.         x_pixel_floor_back_right_edge
  1458.          =((int) ((long) y_out_back)
  1459.          *((long) (x_corner[1][1][0]-x_corner[1][0][0]))
  1460.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1461.          +x_corner[1][0][0];
  1462.         x_pixel_top_back_left_edge
  1463.          =((int) ((long) y_out_back)
  1464.          *((long) (x_corner[0][1][1]-x_corner[0][0][1]))
  1465.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1466.          +x_corner[0][0][1];
  1467.         x_pixel_top_back_right_edge
  1468.          =((int) ((long) y_out_back)
  1469.          *((long) (x_corner[1][1][1]-x_corner[1][0][1]))
  1470.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1471.          +x_corner[1][0][1];
  1472.         x_pixel_floor_front_left_edge
  1473.          =((int) ((long) y_out_front)
  1474.          *((long) (x_corner[0][1][0]-x_corner[0][0][0]))
  1475.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1476.          +x_corner[0][0][0];
  1477.         x_pixel_floor_front_right_edge
  1478.          =((int) ((long) y_out_front)
  1479.          *((long) (x_corner[1][1][0]-x_corner[1][0][0]))
  1480.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1481.          +x_corner[1][0][0];
  1482.         x_pixel_top_front_left_edge
  1483.          =((int) ((long) y_out_front)
  1484.          *((long) (x_corner[0][1][1]-x_corner[0][0][1]))
  1485.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1486.          +x_corner[0][0][1];
  1487.         x_pixel_top_front_right_edge
  1488.          =((int) ((long) y_out_front)
  1489.          *((long) (x_corner[1][1][1]-x_corner[1][0][1]))
  1490.          /((long) ((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1)))
  1491.          +x_corner[1][0][1];
  1492.         x_even=TRUE;
  1493.         x_out_left=0;
  1494.         x_out_right=1;
  1495.         previous_char=' ';
  1496.         for (x=0; x <= max_x; x++)
  1497.           {
  1498.             current_char=page[x][y];
  1499.             if (current_char == 'W')
  1500.               {
  1501.                 if (previous_char != 'W')
  1502.                   x_out_left_most=x_out_left;
  1503.               }
  1504.             else
  1505.               {
  1506.                 if (previous_char == 'W')
  1507.                   {
  1508.                     x_out_right_most=x_out_left;
  1509.                     output_wall(num_columns,x_out_left_most,x_out_right_most,
  1510.                      y_pixel_floor_back,y_pixel_floor_front,
  1511.                      y_pixel_top_back,y_pixel_top_front,
  1512.                      x_pixel_floor_back_left_edge,
  1513.                      x_pixel_floor_back_right_edge,
  1514.                      x_pixel_top_back_left_edge,
  1515.                      x_pixel_top_back_right_edge,
  1516.                      x_pixel_floor_front_left_edge,
  1517.                      x_pixel_floor_front_right_edge,
  1518.                      x_pixel_top_front_left_edge,
  1519.                      x_pixel_top_front_right_edge);
  1520.                   }
  1521.               }
  1522.             previous_char=current_char;
  1523.             x_out_left=x_out_right;
  1524.             x_out_right++;
  1525.             if (x_even)
  1526.               x_out_right+=ROOM_WIDTH_TO_WALL_WIDTH_RATIO;
  1527.             x_even=! x_even;
  1528.           }
  1529.         x_out_right_most=x_out_left;
  1530.         output_wall(num_columns,x_out_left_most,x_out_right_most,
  1531.          y_pixel_floor_back,y_pixel_floor_front,
  1532.          y_pixel_top_back,y_pixel_top_front,
  1533.          x_pixel_floor_back_left_edge,
  1534.          x_pixel_floor_back_right_edge,
  1535.          x_pixel_top_back_left_edge,
  1536.          x_pixel_top_back_right_edge,
  1537.          x_pixel_floor_front_left_edge,
  1538.          x_pixel_floor_front_right_edge,
  1539.          x_pixel_top_front_left_edge,
  1540.          x_pixel_top_front_right_edge);
  1541.         y_out_back=y_out_front;
  1542.         y_out_front++;
  1543.         if (y_even)
  1544.           y_out_front+=ROOM_WIDTH_TO_WALL_WIDTH_RATIO;
  1545.         y_even=! y_even;
  1546.       }
  1547.     return;
  1548.   }
  1549.  
  1550. static void draw_line(
  1551.   int num_rows,
  1552.   int num_columns,
  1553.   int x1,
  1554.   int y1,
  1555.   int x2,
  1556.   int y2)
  1557.     {
  1558.       static int x1_out;
  1559.       static int x1_pixel;
  1560.       static int x1_pixel_left_edge;
  1561.       static int x1_pixel_right_edge;
  1562.       static int x2_out;
  1563.       static int x2_pixel;
  1564.       static int x2_pixel_left_edge;
  1565.       static int x2_pixel_right_edge;
  1566.       static int y1_out;
  1567.       static int y1_pixel;
  1568.       static int y2_out;
  1569.       static int y2_pixel;
  1570.  
  1571.       x1_out=(ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*x1+1;
  1572.       y1_out=(ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*y1+1;
  1573.       x2_out=(ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*x2+1;
  1574.       y2_out=(ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*y2+1;
  1575.       x1_pixel_left_edge
  1576.        =((int) ((long) y1_out)
  1577.        *((long) (x_corner[0][1][1]-x_corner[0][0][1]))
  1578.        /((long) (2*((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1))))
  1579.        +x_corner[0][0][1];
  1580.       x1_pixel_right_edge
  1581.        =((int) ((long) y1_out)
  1582.        *((long) (x_corner[1][1][1]-x_corner[1][0][1]))
  1583.        /((long) (2*((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1))))
  1584.        +x_corner[1][0][1];
  1585.       x1_pixel
  1586.        =((int) (((long) x1_out)
  1587.        *((long) (x1_pixel_right_edge
  1588.        -x1_pixel_left_edge))
  1589.        /((long) (2*((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_columns+1)))))
  1590.        +x1_pixel_left_edge;
  1591.       y1_pixel
  1592.        =((int) ((long) y1_out)
  1593.        *((long) (y_corner[1][1][1]-y_corner[1][0][1]))
  1594.        /((long) (2*((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1))))
  1595.        +y_corner[1][0][1];
  1596.       x2_pixel_left_edge
  1597.        =((int) ((long) y2_out)
  1598.        *((long) (x_corner[0][1][1]-x_corner[0][0][1]))
  1599.        /((long) (2*((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1))))
  1600.        +x_corner[0][0][1];
  1601.       x2_pixel_right_edge
  1602.        =((int) ((long) y2_out)
  1603.        *((long) (x_corner[1][1][1]-x_corner[1][0][1]))
  1604.        /((long) (2*((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1))))
  1605.        +x_corner[1][0][1];
  1606.       x2_pixel
  1607.        =((int) (((long) x2_out)
  1608.        *((long) (x2_pixel_right_edge
  1609.        -x2_pixel_left_edge))
  1610.        /((long) (2*((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_columns+1)))))
  1611.        +x2_pixel_left_edge;
  1612.       y2_pixel
  1613.        =((int) ((long) y2_out)
  1614.        *((long) (y_corner[1][1][1]-y_corner[1][0][1]))
  1615.        /((long) (2*((ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2)*num_rows+1))))
  1616.        +y_corner[1][0][1];
  1617.       moveto(x1_pixel,y1_pixel);
  1618.       lineto(x2_pixel,y2_pixel);
  1619.       return;
  1620.     }
  1621.  
  1622. static void display_solution(
  1623.   int  num_columns,
  1624.   int  num_rows,
  1625.   int  max_x,
  1626.   int  max_y,
  1627.   char **page)
  1628.     {
  1629.       static int delta_index;
  1630.       static int path_found;
  1631.       static int x;
  1632.       static int x_next;
  1633.       static int x_previous;
  1634.       static int y;
  1635.       static int y_next;
  1636.       static int y_previous;
  1637.  
  1638.       setlinestyle(SOLID_LINE,0xffff,THICK_WIDTH);
  1639.       setcolor(SOLUTION_COLOR);
  1640.       x_previous=1;
  1641.       y_previous=-1;
  1642.       x=1;
  1643.       y=0;
  1644.       do
  1645.         {
  1646.           path_found=FALSE;
  1647.           for (delta_index=0; (! path_found); delta_index++)
  1648.             {
  1649.               x_next=x+delta_x[delta_index][0];
  1650.               y_next=y+delta_y[delta_index][0];
  1651.               if ((x_next != x_previous) || (y_next != y_previous))
  1652.                 path_found=(page[x_next][y_next] == 'S');
  1653.             }
  1654.           draw_line(num_rows,num_columns,x,y,x_next,y_next);
  1655.           x_previous=x;
  1656.           y_previous=y;
  1657.           x=x_next;
  1658.           y=y_next;
  1659.         }
  1660.       while ((x != max_x-1) || (y != max_y));
  1661.       return;
  1662.     }
  1663.  
  1664. static void let_user_try_to_solve(
  1665.   int  *key_pressed,
  1666.   int  num_rows,
  1667.   int  num_columns,
  1668.   int  max_x,
  1669.   int  max_y,
  1670.   char **computer_page,
  1671.   char **user_page)
  1672.     {
  1673.       static int delta_index_1;
  1674.       static int frequency;
  1675.       static int passage_found;
  1676.       static int x;
  1677.       static int x_next;
  1678.       static int y;
  1679.       static int y_next;
  1680.  
  1681.       setlinestyle(SOLID_LINE,0xffff,NORM_WIDTH);
  1682.       for (x=0; x <= max_x; x++)
  1683.         for (y=0; y <= max_y; y++)
  1684.           if (computer_page[x][y] == 'W')
  1685.             user_page[x][y]='W';
  1686.           else
  1687.             user_page[x][y]=' ';
  1688.       x=1;
  1689.       y=1;
  1690.       user_page[x][y]='S';
  1691.       setcolor(ADVANCE_COLOR);
  1692.       draw_line(num_rows,num_columns,1,0,x,y);
  1693.       do
  1694.         {
  1695.           do
  1696.             {
  1697.               passage_found=TRUE;
  1698.               *key_pressed=getch();
  1699.               if ((*key_pressed != (int) 'Q')
  1700.               &&  (*key_pressed != (int) 'q')
  1701.               &&  (*key_pressed != (int) 'S')
  1702.               &&  (*key_pressed != (int) 's'))
  1703.                 {
  1704.                   if (*key_pressed == 0)
  1705.                     {
  1706.                       *key_pressed=getch();
  1707.                       switch (*key_pressed)
  1708.                         {
  1709.                           case 72:
  1710.                              delta_index_1=3;
  1711.                              break;
  1712.                           case 77:
  1713.                              delta_index_1=2;
  1714.                              break;
  1715.                           case 80:
  1716.                              delta_index_1=1;
  1717.                              break;
  1718.                           case 75:
  1719.                              delta_index_1=0;
  1720.                              break;
  1721.                           default:
  1722.                             {
  1723.                               passage_found=FALSE;
  1724.                               sound(120);
  1725.                               delay(278);
  1726.                               nosound();
  1727.                               *key_pressed=(int) ' ';
  1728.                               break;
  1729.                             }
  1730.                         }
  1731.                     }
  1732.                   else
  1733.                     {
  1734.                       switch (*key_pressed)
  1735.                         {
  1736.                           case 56:
  1737.                             delta_index_1=3;
  1738.                             break;
  1739.                           case 54:
  1740.                             delta_index_1=2;
  1741.                             break;
  1742.                           case 50:
  1743.                             delta_index_1=1;
  1744.                             break;
  1745.                           case 52:
  1746.                             delta_index_1=0;
  1747.                             break;
  1748.                           case 8:
  1749.                             delta_index_1=0;
  1750.                             break;
  1751.                           default:
  1752.                             passage_found=FALSE;
  1753.                             break;
  1754.                         }
  1755.                     }
  1756.                   if (passage_found)
  1757.                     {
  1758.                       x_next=x+delta_x[delta_index_1][0];
  1759.                       if (x_next <= 0)
  1760.                         passage_found=FALSE;
  1761.                       else
  1762.                         if (x_next >= max_x)
  1763.                           passage_found=FALSE;
  1764.                         else
  1765.                           {
  1766.                             y_next=y+delta_y[delta_index_1][0];
  1767.                             if (y_next <= 0)
  1768.                               passage_found=FALSE;
  1769.                             else
  1770.                               if (y_next > max_y)
  1771.                                 passage_found=FALSE;
  1772.                               else
  1773.                                 if (user_page[x_next][y_next] == 'W')
  1774.                                   passage_found=FALSE;
  1775.                           }
  1776.                     }
  1777.                   if (! passage_found)
  1778.                     {
  1779.                       passage_found=FALSE;
  1780.                       sound(120);
  1781.                       delay(278);
  1782.                       nosound();
  1783.                     }
  1784.                 }
  1785.             }
  1786.           while ((! passage_found)
  1787.           &&     (*key_pressed != (int) 'Q')
  1788.           &&     (*key_pressed != (int) 'q')
  1789.           &&     (*key_pressed != (int) 'S')
  1790.           &&     (*key_pressed != (int) 's'));
  1791.           if ((*key_pressed != (int) 'Q')
  1792.           &&  (*key_pressed != (int) 'q')
  1793.           &&  (*key_pressed != (int) 'S')
  1794.           &&  (*key_pressed != (int) 's'))
  1795.             {
  1796.               x_next+=delta_x[delta_index_1][0];
  1797.               y_next+=delta_y[delta_index_1][0];
  1798.               if (y_next < max_y)
  1799.                 {
  1800.                   if (user_page[x_next][y_next] == 'S')
  1801.                     {
  1802.                       setcolor(BACKOUT_COLOR);
  1803.                       user_page[x][y]=' ';
  1804.                     }
  1805.                   else
  1806.                     {
  1807.                       setcolor(ADVANCE_COLOR);
  1808.                       user_page[x_next][y_next]='S';
  1809.                     }
  1810.                   draw_line(num_rows,num_columns,x,y,x_next,y_next);
  1811.                 }
  1812.               else
  1813.                 {
  1814.                   setcolor(ADVANCE_COLOR);
  1815.                   draw_line(num_rows,num_columns,x,y,max_x-1,max_y);
  1816.                 }
  1817.               x=x_next;
  1818.               y=y_next;
  1819.             }
  1820.         }
  1821.       while ((y_next < max_y)
  1822.       &&     (*key_pressed != (int) 'Q')
  1823.       &&     (*key_pressed != (int) 'q')
  1824.       &&     (*key_pressed != (int) 'S')
  1825.       &&     (*key_pressed != (int) 's'));
  1826.       setcolor(0);
  1827.       outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  1828.        "Arrows - Move    S - Solve    Q - Quit");
  1829.       if    ((*key_pressed != (int) 'Q')
  1830.       &&     (*key_pressed != (int) 'q')
  1831.       &&     (*key_pressed != (int) 'S')
  1832.       &&     (*key_pressed != (int) 's'))
  1833.         {
  1834.           setcolor(NUM_COLORS-4);
  1835.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,"Congratulations!");
  1836.           frequency=10;
  1837.           for (delta_index_1=1; delta_index_1 <= 100;
  1838.            delta_index_1++)
  1839.             {
  1840.               sound(frequency);
  1841.               delay(56);
  1842.               nosound();
  1843.               frequency+=10;
  1844.             };
  1845.           setcolor(0);
  1846.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,"Congratulations!");
  1847.           setcolor(NUM_COLORS-4);
  1848.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  1849.            "S - Solve    Other - Restart program");
  1850.           while (kbhit())
  1851.             {
  1852.               *key_pressed=getch();
  1853.               if (*key_pressed == 0)
  1854.                 {
  1855.                   *key_pressed=getch();
  1856.                   *key_pressed=(int) ' ';
  1857.                 }
  1858.             }
  1859.           *key_pressed=getch();
  1860.           if (*key_pressed == 0)
  1861.             {
  1862.               *key_pressed=getch();
  1863.               *key_pressed=(int) ' ';
  1864.             }
  1865.           setcolor(0);
  1866.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  1867.            "S - Solve    Other - Restart program");
  1868.         }
  1869.       return;
  1870.     }
  1871.